Dedecms框架漏洞复现③
版本影响:
Dedecms v5.7 sp2
漏洞原理分析
简要的一句话来说这个漏洞的形成原因就是:
上传zip文件解压缩时,对于zip文件中的文件后缀过滤不严格,导致getshell
首先分析下源码,我们看到这个路径下的album_add.php
文件中对上传的zip文件中图片的过滤
看到对后缀名的过滤这里,看到是用了一个函数
1 | $fm->GetMatchFiles($tmpzipdir,"jpg|png|gif",$imgs); |
那我们进入这个函数看一下
这里对后缀名的限制主要是由于那个正则表达式,我们来分析一下这个正则
1 | preg_match("/\.(".$fileexp.")/i",$filename) |
\.
:匹配一个点号(.)。点号在正则表达式中需要转义,因为它是一个特殊字符,表示任意字符的通配符。
这个正则表达式的作用是在字符串 $filename
中寻找以 “jpg”、”png” 或 “gif” 为扩展名的文件。如果匹配成功,preg_match()
函数会返回 1,否则返回 0
但是这里就有一个bug,就是只要他在我们的文件名中匹配到了.jpg
、.png
、.gif
则视为匹配成功,这样的话我们就可以用1.jpg.php
这个格式进行绕过,从而导致任意文件上传
漏洞复现
首先官网下载对应版本的源码之后,解压到phpstudy中,然后访问/DedeCMS-V5.7-UTF8-SP2/uploads/install/index.php
进行程序的安装,之后登录的用户名和密码都用默认的管理员的admin
登录即可
然后我们创建一个1.jpg.php
文件,里面写入phpinfo或者写入一句话木马
1 | <?php phpinfo();?> |
然后将这个文件压缩上传到文件式管理器的soft
目录下
然后我们先去网站栏目管理这里去随便创建一个图片集栏目
创建完成之后,我们访问/DedeCMS-V5.7-UTF8-SP2/uploads/dede/album_add.php
,选择从 从ZIP压缩包中解压图片
然后发布,发布成功之后选择预览文档
复现成功
漏洞修补
这里我一开始想的修补方式是将正则改为,将文件名的最后几个字符和允许的后缀名进行匹配,而不是对整个文件名都进行匹配。然后我看了已经修复的版本,最后的修复方法如下,只有这个函数的定义的最后一句不一样,这里替换了正则
用了in_array()
函数,函数定义如下
1 | function in_array(mixed $needle, array $haystack, bool $strict = false): bool {} |
这个函数的作用是在 $haystack
数组中搜索是否存在与 $needle
值相等的元素,如果存在则返回 true
,否则返回 false
。在给定的代码中,in_array()
函数用于判断文件的扩展名是否存在于分割后的扩展名数组中,即 $needle
是文件的扩展名,$haystack
是扩展名数组。这里的
1 | pathinfo($filename, PATHINFO_EXTENSION) |
直接取的文件的后缀名去和数组里允许的那三个后缀名进行对比,进而防止了1.jpg.php
这种绕过手法
复现过程中问题
在我第一次发布的时候,发现一直有报错
1 | 把数据保存到数据库附加表 dede_addonimages 时出错,请把相关信息提交给DedeCMS官方。You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'row,col,isrm,ddmaxwidth,pagepicnum,body) Values('4','2','','0.0.' at line 1 |
最后通过这篇文章提到的方法解决,主要就是版本问题我们需要给关键字加上反引号